#include <stdio.h>
#include <setjmp.h>		/* jmp_buf */
#include <stdlib.h>
#include <string.h>


int var()
{
	char ch = 'a';
	int a = (int)ch;

	printf("%d %c\n", a, ch);

	
	#define PI 3.14
	#define OUT	314
	int b = PI;

	printf("%d\n", b);	// 3
	printf("%f\n", PI);	// 3.140000
	printf("%d\n", PI);	// 1374389535
	printf("%d\n", OUT);// 314
}



static jmp_buf buf;
void jmp()
{
	volatile int b;

	b = 3;
	if (setjmp(buf) != 0) {
		printf("%d\n", b);	// 5
		exit(0);
	}

	b = 5;
	longjmp(buf, 1);
}

void snode()
{
	struct node
	{
		int a;
		int b;
		int c;
	};

	struct node s = {3, 5, 6};
	struct node *pt = &s;

	printf("%d\n", sizeof(struct node));	// 12
	printf("%d\n", *(int *)pt);				// 3
}



void d()
{
	printf("%d\n", 1 % 2);	// 1
}



// x 的 n 次幂
int foo(int x, int n)
{
	int val;
	val = 1;

	if (n > 0) {
		if (n % 2 == 1) 
			val = val * x;
		val = val * foo(x * x, n / 2);
		printf("%d\n", val);
	}
	

	return val;
}




void arr(int [][3]);

void inv_arr()
{
	int a[3][3] = {{1,2,3},{4,5,6},{7,8,9}};
	arr(a);
	printf("%d\n", a[2][1]);	// 9
}

void arr(int b[][3])
{
	++b;			// 移向 a[1][0], 使a[1][0]变为b[0][0]
	b[1][1] = 9;
}


int six()
{
	int a, b, c, d;

	a = 3;
	b = 5;
	c = a, b;
	d = (a, b);

	printf("c = %d\n", c);	// 3
	printf("d = %d\n", d);	// 5
}


void ser()
{
	int a[][3] = { 1, 2, 3, 4, 5, 6};
	int (*ptr)[3] = a;

	printf("%d %d\n", (*ptr)[1], (*ptr)[2]);	// 2	3
	++ptr;
	printf("%d %d\n", (*ptr)[1], (*ptr)[2]);	// 5	6
}


int *f1(void)
{  
	int x =10; 
	return(&x);

	// 它返回一个局部变量的指针，局部变量是保存在stack中的,退出函数后，
	// 局部变量就销毁了，保留其指针没有意义，因为其指向的stack空间可能被其他变量覆盖了
}

int *f2(void)
{  
	int*ptr;  
	*ptr =10;  
	return ptr;

	// ptr是局部变量，未初始化，它的值是未知的，*ptr不知道指向哪里了，
	// 直接给*ptr赋值可能会覆盖重要的系统变量，这就是通常说的野指针的一种
}

int *f3(void)
{  
	int *ptr;  
	ptr=(int*) malloc(sizeof(int));  
	return ptr;
}


void nine()
{  
	int i=3;  
	int j;
	
	j = sizeof(++i+ ++i);	// 4
	printf("%d i=%d j=%d\n", sizeof(i), i ,j);	// 4	3	4
}

void ten()
{  
	char p;  
	char buf[10] ={ 1,2,3,4,5,6,9,8};  

	// 考查什么时候数组就是指针.对某些类型T而言，如果一个表达式是 T[]  (T的数组),  
	// 这个表达式的值实际上就是指向该数组的第一个元素的指针.
	// 所以 (buf+1)[5] 实际上就是 *(buf +6) 或者 buf[6]

	p = (buf+1)[5];  

	printf("%d\n" , p);	// 9
}


void ff(char**);
void elv()
{  
	char * argv[] = { "ab" ,"cd" , "ef" ,"gh", "ij" ,"kl" };  
	
	ff( argv );
}
void ff( char **p )
{  
	char * t;
	
	t = ( p += sizeof(int) )[-1];

	// sizeof(int)的值是4,所以 p += sizeof(int) 指向 argv[4],这点估计大家都没有什么疑问
	// (p + =sizeof(int))[-1] 指向 argv[3],能理解吗，因为(p += sizeof(int))[-1]  
	// 就相当于 (p += 4)[-1] ,也就是(p + 4 - 1)

	printf( "%s\n" , t);
}


int counter (int i)
{  
	static int count = 0;	// 初始化一次, 然后值不变. 这句只执行一次.
	count = count +i;  
	printf("%d\n", count);

	return (count );
}

void twl()
{  
	int i , j;
	
	for (i=0; i <=5; i++)    
		j = counter(i);

	printf("%d\n", j);
}

int main()
{	
	//var();
	//jmp();		
	//snode();
	//d();
	//foo(2,3);	// 2 * 2 * 2 = 8
	//inv_arr();
	//six();
	//ser();
	//nine();
	ten();
	elv();
	twl();


	return 0;
}


